#ifndef __REGISTER__
#define __REGISTER__

#include <string>
#include <map>
#include <memory>

class TaskBase
{
public:

    using sptr = std::shared_ptr<TaskBase>;

    static std::string Name();

    static sptr Create();

    using CreateFunc = sptr (*)();

private:
    std::string m_name = "";
};



class Factory
{
public:
    static TaskBase::sptr CreateTask(const std::string& name)
    {
        if (m_factory.find(name) == m_factory.end()) {
            return nullptr;
        }

        return m_factory[name]();
    }

    static Factory Create()
    {
        static Factory instance;
        return instance;
    }


    static std::map<std::string, TaskBase::CreateFunc> m_factory;

private:
    Factory() {}

}; // class Factory

std::map<std::string, TaskBase::CreateFunc> Factory::m_factory = {};

class Register
{
public:
    Register(const std::string& name, TaskBase::CreateFunc func) {
        if (Factory::m_factory.find(name) != Factory::m_factory.end()) {
            return;
        }

        Factory::m_factory[name] = func;
    }
private:

}; // class Register

#define REGISTER_TASK(name) \
    Register g_Instance_##name(#name, name::Create);


class Task1: public TaskBase
{
public:
    static std::shared_ptr<TaskBase> Create() {return std::make_shared<Task1>();}
};

REGISTER_TASK(Task1);


#endif // __REGISTER__